package com.ef.service.impl;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;

import com.ef.constant.EUserTodoObject;
import com.ef.constant.EUserTodoStatus;
import com.ef.constant.EUserTodoType;
import com.ef.constant.StatusType;
import com.ef.dao.LeadsDao;
import com.ef.dao.TodoEventDao;
import com.ef.domain.Leads;
import com.ef.domain.School;
import com.ef.domain.UserTodoEvent;
import com.ef.service.LeadsService;
import com.ef.util.CalendarUtil;
import com.ef.util.CustomExample;
import com.ef.util.PaginationSupport;

public class LeadsServiceImpl extends BaseServiceImpl implements LeadsService {

	private LeadsDao leadsDao;

	private TodoEventDao todoEventDao;

	public void delete(Leads entity) {
		entity.setStatus(StatusType.INVALID);
		leadsDao.update(entity);
	}

	public PaginationSupport<Leads> findByExample(CustomExample<Leads> example,
			int startIndex, int pageSize) {

		return leadsDao.findPageByExample(example, startIndex, pageSize);
	}

	public Leads findById(Long id) {

		return leadsDao.findById(id);
	}

	public void saveOrUpdate(Leads entity) {

		leadsDao.clear();
		leadsDao.saveOrUpdate(entity);
	}

	public List<Leads> findShowUps(Date start, Date end) {
		DetachedCriteria criterion = DetachedCriteria.forClass(Leads.class);
		if (start != null) {
			criterion.add(Restrictions.ge("showTime", CalendarUtil
					.getBeginOfDay(start)));
		}
		if (end != null) {
			CalendarUtil.getEndOfDay(end);
			criterion.add(Restrictions.le("showTime", CalendarUtil
					.getEndOfDay(end)));
		}
		criterion.add(Restrictions.eq("status", StatusType.VALID));
		criterion.addOrder(Order.asc("showTime"));
		return leadsDao.findAllByCriteria(criterion);
	}

	public List<Leads> findShowUpsBySchool(Date start, Date end, School school) {
		DetachedCriteria criterion = DetachedCriteria.forClass(Leads.class);
		if (start != null) {
			criterion.add(Restrictions.ge("showTime", CalendarUtil
					.getBeginOfDay(start)));
		}
		if (end != null) {
			CalendarUtil.getEndOfDay(end);
			criterion.add(Restrictions.le("showTime", CalendarUtil
					.getEndOfDay(end)));
		}
		criterion.add(Restrictions.eq("status", StatusType.VALID));
		criterion.createCriteria("school").add(
				Restrictions.eq("id", school.getId()));
		criterion.addOrder(Order.asc("showTime"));
		return leadsDao.findAllByCriteria(criterion);
	}

	public LeadsDao getLeadsDao() {
		return leadsDao;
	}

	public void setLeadsDao(LeadsDao leadsDao) {
		this.leadsDao = leadsDao;
	}

	public List<Leads> findByMobileOrPhone(String mobile, String phone) {
		DetachedCriteria criterion = DetachedCriteria.forClass(Leads.class);
		criterion.add(Restrictions.and(Restrictions.or(Restrictions.eq(
				"mobileTelephone", mobile), Restrictions.or(Restrictions.eq(
				"telephone", phone), Restrictions
				.or(Restrictions.eq("telephone", mobile), Restrictions.eq(
						"mobileTelephone", phone)))), Restrictions.eq("status",
				StatusType.VALID)));
		// criterion.add(Restrictions.and(Restrictions
		// .or(Restrictions.eq("mobileTelephone", mobile), Restrictions
		// .eq("telephone", phone)), Restrictions.eq("status",
		// StatusType.VALID)));
		return leadsDao.findAllByCriteria(criterion);
	}

	public List<Leads> findByTelephone(String tell) {
		DetachedCriteria criterion = DetachedCriteria.forClass(Leads.class);
		Disjunction or = Restrictions.disjunction();
		Property myProperty = Property.forName("telephone");
		or.add(myProperty.like("%" + tell.trim() + "%"));
		myProperty = Property.forName("mobileTelephone");
		or.add(myProperty.like("%" + tell.trim() + "%"));
		myProperty = Property.forName("companyTelephone");
		or.add(myProperty.like("%" + tell.trim() + "%"));
		myProperty = Property.forName("otherTelephone");
		or.add(myProperty.like("%" + tell.trim() + "%"));
		myProperty = Property.forName("eliteCard");
		or.add(myProperty.like("%" + tell.trim() + "%"));
		criterion.add(or);
		criterion.add(Restrictions.eq("status", StatusType.VALID));
		return leadsDao.findAllByCriteria(criterion);
	}

	public List<Leads> findByTelephoneAccurate(String tell) {
		DetachedCriteria criterion = DetachedCriteria.forClass(Leads.class);
		Disjunction or = Restrictions.disjunction();
		Property myProperty = Property.forName("telephone");
		or.add(myProperty.eq(tell.trim()));
		myProperty = Property.forName("mobileTelephone");
		or.add(myProperty.eq(tell.trim()));
		myProperty = Property.forName("companyTelephone");
		or.add(myProperty.eq(tell.trim()));
		myProperty = Property.forName("otherTelephone");
		or.add(myProperty.eq(tell.trim()));
		myProperty = Property.forName("eliteCard");
		or.add(myProperty.eq(tell.trim()));
		criterion.add(or);
		criterion.add(Restrictions.eq("status", StatusType.VALID));
		return leadsDao.findAllByCriteria(criterion);
	}

	public List<Leads> findByAnything(String qitem, int max) {
		StringBuffer hql = new StringBuffer(
				"From Leads where (lower(name) like '%");
		hql.append(qitem);
		hql.append("%' or telephone like '%");
		hql.append(qitem);
		hql.append("%' or mobileTelephone like '%");
		hql.append(qitem);
		hql.append("%' or companyTelephone like '%");
		hql.append(qitem);
		hql.append("%' or otherTelephone like '%");
		hql.append(qitem);
		hql.append("%' or lower(eliteCard) like '%");
		hql.append(qitem);
		hql.append("%') and status='VALID' ");

		return leadsDao.findMultiAll(hql.toString(), 0, max);
	}

	public List<Leads> findByAnythingInSchool(String qitem, Long schoolId,
			int max) {

		StringBuffer hql = new StringBuffer(
				"From Leads where (lower(name) like '%");
		hql.append(qitem);
		hql.append("%' or telephone like '%");
		hql.append(qitem);
		hql.append("%' or mobileTelephone like '%");
		hql.append(qitem);
		hql.append("%' or companyTelephone like '%");
		hql.append(qitem);
		hql.append("%' or otherTelephone like '%");
		hql.append(qitem);
		hql.append("%' or lower(eliteCard) like '%");
		hql.append(qitem);
		hql.append("%') and status='VALID' and school.id=");
		hql.append(schoolId);

		return leadsDao.findMultiAll(hql.toString(), 0, max);

	}

	public List<Leads> findByAnythingByCC(String qitem, Long ccid, int max) {
		StringBuffer hql = new StringBuffer(
				"From Leads where (lower(name) like '%");
		hql.append(qitem);
		hql.append("%' or telephone like '%");
		hql.append(qitem);
		hql.append("%' or mobileTelephone like '%");
		hql.append(qitem);
		hql.append("%' or companyTelephone like '%");
		hql.append(qitem);
		hql.append("%' or otherTelephone like '%");
		hql.append(qitem);
		hql.append("%' or lower(eliteCard) like '%");
		hql.append(qitem);
		hql.append("%') and status='VALID' and cc.id=");
		hql.append(ccid);
		return leadsDao.findMultiAll(hql.toString(), 0, max);

	}

	public static int lastRefreshDay = -1;

	public void refreshDeferLeads() {
		Calendar calendar = Calendar.getInstance();
		int day = calendar.get(Calendar.DAY_OF_YEAR);
		if (lastRefreshDay == -1 || lastRefreshDay != day) {// 不是同一天
			System.out
					.println("------------------refreshDeferLeads---------------------------------------------");
			DetachedCriteria criterion = DetachedCriteria.forClass(Leads.class);
			criterion.add(Restrictions.eq("status", StatusType.VALID));
			criterion.add(Restrictions.ge("deferEndTime", CalendarUtil
					.getBeginOfDay(new Date())));
			criterion.add(Restrictions.le("deferEndTime", CalendarUtil
					.getEndOfDay(new Date())));
			List<Leads> list = leadsDao.findAllByCriteria(criterion);
			for (Leads leads : list) {
				String title = "NOTE:leads defer expire. ";
				UserTodoEvent todoEvent = new UserTodoEvent();
				todoEvent.setCreateTime(new Date());
				todoEvent.setTodoType(EUserTodoType.Call);
				todoEvent.setGoAction("/customer/PersonalTouch/call?id="
						+ leads.getId());
				todoEvent.setCreateUser(leads.getCr());
				todoEvent.setReminderStartTime(new Date());
				todoEvent.setReminderEndTime(CalendarUtil
						.getEndOfDay(CalendarUtil.getEndOfDay(new Date())));
				todoEvent.setToObject(EUserTodoObject.MySelf);
				todoEvent.setToUser(leads.getCr());
				todoEvent.setStatus(EUserTodoStatus.Valid);
				String todoEventComments = leads.getName()
						+ " leads defer expire !";
				todoEvent.setDetail(todoEventComments);
				todoEvent.setTitle(title);
				todoEventDao.saveOrUpdate(todoEvent);
			}
			lastRefreshDay = day;
		}
	}

	/**
	 * 找重复的leads 根据电话号码进行判断;
	 * 
	 * @param leads
	 * @return
	 */
	public List<Leads> findDuplicateLeads(Leads leads) {
		DetachedCriteria criterion = DetachedCriteria.forClass(Leads.class);
		Disjunction or = Restrictions.disjunction();
		if (leads.getTelephone() != null
				&& leads.getTelephone().trim().length() > 0) {
			Property myProperty = Property.forName("telephone");
			or.add(myProperty.eq(leads.getTelephone().trim()));
			myProperty = Property.forName("mobileTelephone");
			or.add(myProperty.eq(leads.getTelephone().trim()));
			myProperty = Property.forName("companyTelephone");
			or.add(myProperty.eq(leads.getTelephone().trim()));
			myProperty = Property.forName("otherTelephone");
			or.add(myProperty.eq(leads.getTelephone().trim()));
		}
		if (leads.getMobileTelephone() != null
				&& leads.getMobileTelephone().trim().length() > 0) {
			Property myProperty = Property.forName("telephone");
			or.add(myProperty.eq(leads.getMobileTelephone().trim()));
			myProperty = Property.forName("mobileTelephone");
			or.add(myProperty.eq(leads.getMobileTelephone().trim()));
			myProperty = Property.forName("companyTelephone");
			or.add(myProperty.eq(leads.getMobileTelephone().trim()));
			myProperty = Property.forName("otherTelephone");
			or.add(myProperty.eq(leads.getMobileTelephone().trim()));
		}
		if (leads.getCompanyTelephone() != null
				&& leads.getCompanyTelephone().trim().length() > 0) {
			Property myProperty = Property.forName("telephone");
			or.add(myProperty.eq(leads.getCompanyTelephone().trim()));
			myProperty = Property.forName("mobileTelephone");
			or.add(myProperty.eq(leads.getCompanyTelephone().trim()));
			myProperty = Property.forName("companyTelephone");
			or.add(myProperty.eq(leads.getCompanyTelephone().trim()));
			myProperty = Property.forName("otherTelephone");
			or.add(myProperty.eq(leads.getCompanyTelephone().trim()));
		}
		if (leads.getOtherTelephone() != null
				&& leads.getOtherTelephone().trim().length() > 0) {
			Property myProperty = Property.forName("telephone");
			or.add(myProperty.eq(leads.getOtherTelephone().trim()));
			myProperty = Property.forName("mobileTelephone");
			or.add(myProperty.eq(leads.getOtherTelephone().trim()));
			myProperty = Property.forName("companyTelephone");
			or.add(myProperty.eq(leads.getOtherTelephone().trim()));
			myProperty = Property.forName("otherTelephone");
			or.add(myProperty.eq(leads.getOtherTelephone().trim()));
		}
		criterion.add(or);
		criterion.add(Restrictions.eq("status", StatusType.VALID));
		return leadsDao.findAllByCriteria(criterion);
	}

	public TodoEventDao getTodoEventDao() {
		return todoEventDao;
	}

	public void setTodoEventDao(TodoEventDao todoEventDao) {
		this.todoEventDao = todoEventDao;
	}

	// 导出Pte的业绩
	public List<Object> exportPteResults(String start, String end,
			String tmList, Long selMarketingPolicyId, String selleadsType,
			Long selAdChannelId, Long selSchoolId) {
		return leadsDao
				.exportPteResults(start, end, tmList, selMarketingPolicyId,
						selleadsType, selAdChannelId, selSchoolId);
	}

	// 导出Pte的业绩
	public List<Object> exportPteResults(String start, String end,
			Long selMarketingPlanId,Long selCreateUserId,Long teamid) {
		return leadsDao.exportPteResults(start, end, selMarketingPlanId,selCreateUserId,teamid);
	}
	public List<Object> exportPteLeadResults(String start, String end,
			Long selMarketingPlanId,Long selCreateUserId,Long teamid) {
		return leadsDao.exportPteLeadResults(start, end, selMarketingPlanId,selCreateUserId,teamid);
	}
}
